#!/usr/bin/env python
# -*- coding:utf-8 -*-


'''
@Author : shouke
'''

import re
import logging
import random

from config.config import request_response_field_map
from components.decoraters.action_decorater import ActionDecorator

logger = logging.getLogger(__name__)

class RegexpExtracter(object):
    @ActionDecorator.action_register('extract_by_regexp', 'RegexpExtracter', 'extract_by_regexp', __name__)
    @classmethod
    def extract_by_regexp(self, config:dict, *args, **kwargs):
        '''
        正则表达式提取器
        :param config 正则提取配置信息，如下
        {
            "refName": "userInfo", #引用名称 # 不能为空
            "express": 'username":"(.+?)",.+token":"(.+?)"', #正则表达式
            "target": "body", # 提取源对象目标域
            "template": "$1$$2$$0$", # 默认为$0$ $0$-取分组0数据（分组1到分组n按顺序拼接起来的数据） $1$-取分组1数据 $2$-取分组2数据 以此类推,如果给定索引越界
            "matchNo": 0 # 可选配置，默认为0，取分组中指定匹配索引的数据 matchNo 0开始，0表示随机，1表示取分组中第一个值 2 取第二个分组的值 以此类推， 如果越界，提取结果为空
            "response":responseObj # 提取源对象-请求响应、程序输出
        }
        '''

        logger.debug('正在执行正则提取')
        user = kwargs['user']
        user_resource_dict = user.user_resource_dict[user.chain_id]
        response = config.get('response')
        if config['target'].lower() not in request_response_field_map:
            logger.error('【正则提取结果】：提取失败，提取源配置错误，可选值为：%s' % ','.join(list(request_response_field_map.keys())))
            return

        source_target = str(getattr(response, request_response_field_map[config['target'].lower()]))
        config['target'] = source_target
        re_match_list = re.findall(config.get('express'), source_target)
        variable = config.get('refName').strip()
        template = config.get('template')
        match_no = config.get('matchNo')

        logger.debug('【引用名称为】：%s' % variable)
        logger.debug('【正则提取表达式】：%s' % config.get('express'))
        logger.debug('【提取源对象】：%s' % source_target)
        logger.debug('【提取模板】：%s' % template)
        logger.debug('【匹配数字】：%s' % match_no)
        if not re_match_list:
            logger.warn('【正则提取结果】：匹配结果为空')
            return

        if not variable:
            logger.debug('【正则提取结果】：提取失败，未配置引用变量')
            return
        if not match_no: # 随机获取
            match_result_choice = random.sample(re_match_list, 1)
        else:
            match_result_choice = re_match_list[match_no - 1:match_no]

        if match_result_choice:
            group_zero_name = '%s_g0' % variable
            user_resource_dict[group_zero_name] = ''
            for item_index, item in enumerate(match_result_choice[0]):
                group_name = '%s_g%s' % (variable, item_index + 1)
                user_resource_dict[group_name] =  item
                user_resource_dict[group_zero_name] += item

            # 替换模板
            target_group_index_list = re.findall('(\$\s*\d+\s*\$?)', template)
            if target_group_index_list:
                for item in target_group_index_list:
                    index = item.strip('$').strip()
                    group_name = '%s_g%s' % (variable, index)
                    if group_name in user_resource_dict:
                        template = template.replace(item, user_resource_dict[group_name])
            else:
                template = user_resource_dict[group_zero_name]

            user_resource_dict[variable] = template
            logger.debug('【正则提取结果】：提取成功，提取值为：%s' % template)
        else:
            logger.debug('【正则提取结果】：提取失败，匹配索引越界')
